package gupao.concurrency.forecaster;

import gupao.concurrency.enums.TrafficChannelEnum;
import gupao.concurrency.model.ForecastConfig;
import gupao.concurrency.service.ForcastConfigService;
import gupao.concurrency.threadpool.ForecastRunnableTask;
import gupao.concurrency.threadpool.ForecastScheduledExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.Objects;

@Slf4j
public class ChannelForcaster {

    private final TrafficChannelEnum channelEnum;
    private final ForecastScheduledExecutor scheduler;
    private final ForcastConfigService configService;

    public ChannelForcaster(TrafficChannelEnum channelEnum, ForecastScheduledExecutor forcastScheduledExecutor, ForcastConfigService configService) {
        this.channelEnum = channelEnum;
        this.scheduler = forcastScheduledExecutor;
        this.configService = configService;
    }

    @Scheduled(initialDelay = 10000, fixedDelay = 20 * 1000)
    public void schedule(){
        ForecastConfig newConfig = configService.queryForcastConfig();
        if(newConfig == null){
            scheduler.markCancel(channelEnum);
            return;
        }

        if(newConfig.getChannelEnum() != channelEnum){
            scheduler.markCancel(channelEnum);
            return;
        }

        ForecastRunnableTask runningTask = scheduler.getRunningTask(channelEnum);
        if(runningTask == null){
            scheduler.scheduleForecastTask(newConfig, channelEnum);
            return;
        }

        ForecastConfig runningConfig = runningTask.getForecastConfig().get();
        if(!Objects.equals(runningConfig.getTimeWindowSeconds(), newConfig.getTimeWindowSeconds())){
            scheduler.rescheduleAfterCancel(channelEnum, newConfig);
            return;
        }

        if(runningConfig.getThreshold() != newConfig.getThreshold()
            || runningConfig.getTopN() != newConfig.getTopN() ){
            runningTask.setForecastConfig(newConfig);
            return;
        }

        log.info("traffic forecast config no changes..");
    }
}
